package run.iget.admin.system.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import run.iget.admin.system.constant.AdminSystemConst;
import run.iget.admin.system.entity.Permission;
import run.iget.admin.system.entity.table.PermissionTableDef;
import run.iget.admin.system.entity.table.RolePermissionTableDef;
import run.iget.admin.system.enums.PermissionType;
import run.iget.admin.system.enums.SystemExceptionEnum;
import run.iget.admin.system.mapper.PermissionMapper;
import run.iget.admin.system.service.PermissionService;
import run.iget.admin.system.service.RolePermissionService;
import run.iget.framework.common.util.ExceptionThrowUtils;
import run.iget.framework.common.util.TreeUtils;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * <p>
 * 授权中心：权限资源表 服务实现类
 * </p>
 *
 * @author 大周
 * @since 2022-02-07
 */
@Service
public class PermissionServiceImpl extends ServiceImpl<PermissionMapper, Permission> implements PermissionService {
    @Resource
    private RolePermissionService rolePermissionService;

    @Override
    public List<Permission> listByRoleIds(String roleIds) {
        if (StrUtil.isBlank(roleIds)) {
            return null;
        }
        long[] longs = StrUtil.splitToLong(roleIds, StrUtil.C_COMMA);
        Set<Long> collect = Arrays.stream(longs).boxed().collect(Collectors.toSet());
        return listByRoleIds(collect);
    }

    @Override
    public List<Permission> listByRoleIds(List<Long> roleIds) {
        if (CollectionUtil.isEmpty(roleIds)) {
            return new ArrayList<>(0);
        }
        return listByRoleIds(roleIds.stream().collect(Collectors.toSet()));
    }

    @Override
    public List<Permission> listByRoleIds(Set<Long> roleIds) {
        if (CollectionUtil.isEmpty(roleIds)) {
            return new ArrayList<>(0);
        }
        // 构造查询条件
        QueryWrapper queryWrapper = QueryWrapper.create()
                .select(PermissionTableDef.PERMISSION.ALL_COLUMNS)
                .from(PermissionTableDef.PERMISSION)
                .leftJoin(RolePermissionTableDef.ROLE_PERMISSION)
                .on(PermissionTableDef.PERMISSION.ID.eq(RolePermissionTableDef.ROLE_PERMISSION.PERMISSION_ID))
                .where(RolePermissionTableDef.ROLE_PERMISSION.ROLE_ID.in(roleIds));
        return this.mapper.selectListByQuery(queryWrapper);
    }

    @Override
    public List<Permission> listTreeByRoleIds(String roleIds) {
        return listToTree(listByRoleIds(roleIds));
    }

    @Override
    public List<Permission> listTreeByRoleIds(Set<Long> roleIds) {
        return listToTree(listByRoleIds(roleIds));
    }

    @Override
    public List<Permission> listMenus() {
        List<Permission> list = super.list();
        return buildMenus(list);
    }

    @Override
    public List<Permission> listMenus(String permissionId) {
        QueryWrapper where = QueryWrapper.create().where(PermissionTableDef.PERMISSION.PID.eq(permissionId));
        List<Permission> list = super.list(where);
        return buildMenus(list);
    }

    @Override
    public List<Permission> listToTree(List<Permission> permissions) {
        if (CollUtil.isEmpty(permissions)) {
            return null;
        }
        List<Permission> build = TreeUtils.build(permissions);
        return build;
    }

    @Override
    public List<Permission> buildMenus(List<Permission> permissions) {
        if (CollUtil.isEmpty(permissions)) {
            return null;
        }
        List<Permission> collect = permissions.stream()
                .filter(item -> PermissionType.BUTTON.getValue() != item.getType()).collect(Collectors.toList());
        //        List<Permission> menuTreeNodes = permissions.stream()
        //                .filter(item -> PermissionType.BUTTON.getValue() != item.getType()).map(item -> {
        //                    Permission menuTreeNode = new Permission();
        //                    menuTreeNode.set(item.getUri());
        //                    menuTreeNode.setName(item.getName());
        //                    menuTreeNode.setIcon(item.getIcon());
        //                    menuTreeNode.setId(item.getId());
        //                    menuTreeNode.setPid(item.getPid());
        //                    return menuTreeNode;
        //                }).collect(Collectors.toList());
        if (CollUtil.isEmpty(collect)) {
            return null;
        }
        return TreeUtils.build(collect);
    }

    @Override
    @Transactional
    public void add(Permission entity) {
        if (Objects.equals(entity.getPid(), AdminSystemConst.ROOT_NODE_ID)) {
            entity.setType(PermissionType.CATALOG.getValue());
        } else {
            // 查询父节点
            Permission parentNode = this.getById(entity.getPid());
            ExceptionThrowUtils.ofNull(parentNode, SystemExceptionEnum.PARENT_NODE_DOES_NOT_EXIST);
            // 根据父节点自动填充当前节点的类型
            ExceptionThrowUtils.ofTrue(Objects.equals(parentNode.getType(), PermissionType.BUTTON.getValue()),
                    SystemExceptionEnum.NOT_HAS_CHILD_NODE);
            entity.setType(PermissionType.getSubType(parentNode.getType()).getValue());
        }
        // 防止破坏id自动生成
        entity.setId(null);
        this.save(entity);
        // 将新增的权限关联到默认角色上
        rolePermissionService.relationNewPermission(entity.getId());
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

}
